import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
import serial
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu

#  通过modbus协议连接设备，并设置串口为COM4，波特率为9600，数据位为8位，无奇偶校验，停止位为1
configuration = modbus_rtu.RtuMaster(serial.Serial(port="COM4", baudrate=9600, bytesize=8, parity='N', stopbits=1))

configuration.set_timeout(5.0)


class MyWindow(QWidget):
    def __init__(self):
        super().__init__()  # 继承父类
        self.ui = self.ui = uic.loadUi("./MainWindow.ui")   # 读取ui文件

        # 绑定信号与槽函数
        self.ui.Env_Temp_PushButton.clicked.connect(self.env_temp)  # 环境温度按钮被点击后读取环境温度
        self.ui.Valve_Pre_Temp_PushButton.clicked.connect(self.pre_temp)  # 阀前温度按钮被点击后读取阀前温度
        self.ui.Valve_Post_Temp_PushButton.clicked.connect(self.post_temp)  # 阀后温度按钮被点击后读取阀后温度

    def env_temp(self):
        """
        此函数为读取RS20K-C的CH1口，对应环境温度，读取后将结果显示在应用的文本框中

        参数1：initial_data:数组，数据类型为整型，得到的值为实际温度值的十倍
        参数2：final_data：数据类型为字符串，因为TextBrowser输出的内容必须为字符串。输出的温度为实际温度

        返回值：应用的Env_Temp_TextBrowser返回实际温度值

        异常类型：输出如果不是字符串会导致Env_Temp_TextBrowser输出异常并终止应用

        """
        # 通过modbus协议读取初始数值，从站号为1，读寄存器，起始地址为40，长度为1
        initial_data = configuration.execute(1, cst.READ_HOLDING_REGISTERS, 40, 1)

        # 提取数组里的第一个数除以10得到实际温度，并转换为字符串形式
        final_data = str(initial_data[0] / 10)

        # python内输出结果
        print("环境温度为：" + final_data + "℃")

        # 应用内文本框显示温度
        self.ui.Env_Temp_TextBrowser.setText(final_data + "℃")

        # 立刻显示
        self.ui.Env_Temp_TextBrowser.repaint()

    def pre_temp(self):
        """
                此函数为读取RS20K-C的CH2口，对应阀前温度，读取后将结果显示在应用的文本框中

                参数1：initial_data:数组，数据类型为整型，得到的值为实际温度值的十倍
                参数2：final_data：数据类型为字符串，因为TextBrowser输出的内容必须为字符串。输出的温度为实际温度

                返回值：应用的Valve_Pre_Temp_TextBrowser返回实际温度值

                异常类型：输出如果不是字符串会导致Valve_Pre_Temp_TextBrowser输出异常并终止应用

                """
        # 通过modbus协议读取初始数值，从站号为1，读寄存器，起始地址为41，长度为1
        initial_data = configuration.execute(1, cst.READ_HOLDING_REGISTERS, 41, 1)

        # 提取数组里的第一个数除以10得到实际温度，并转换为字符串形式
        final_data = str(initial_data[0] / 10)

        # python内输出结果
        print("阀前温度为：" + final_data + "℃")

        # 应用内文本框显示温度
        self.ui.Valve_Pre_Temp_TextBrowser.setText(final_data + "℃")

        # 立刻显示
        self.ui.Valve_Pre_Temp_TextBrowser.repaint()

    def post_temp(self):
        """
                       此函数为读取RS20K-C的CH3口，对应阀后温度，读取后将结果显示在应用的文本框中

                       参数1：initial_data:数组，数据类型为整型，得到的值为实际温度值的十倍
                       参数2：final_data：数据类型为字符串，因为TextBrowser输出的内容必须为字符串。输出的温度为实际温度

                       返回值：应用的Valve_Post_Temp_TextBrowser返回实际温度值

                       异常类型：输出如果不是字符串会导致Valve_Post_Temp_TextBrowser输出异常并终止应用

                       """
        # 通过modbus协议读取初始数值，从站号为1，读寄存器，起始地址为42，长度为1
        initial_data = configuration.execute(1, cst.READ_HOLDING_REGISTERS, 42, 1)

        # 提取数组里的第一个数除以10得到实际温度，并转换为字符串形式
        final_data = str(initial_data[0] / 10)

        # python内输出结果
        print("阀后温度为：" + final_data + "℃")

        # 应用内文本框显示温度
        self.ui.Valve_Post_Temp_TextBrowser.setText(final_data + "℃")

        # 立刻显示
        self.ui.Valve_Post_Temp_TextBrowser.repaint()


if __name__ == '__main__':
    app = QApplication(sys.argv)  # 初始化窗口系统并构造一个应用程序

    w = MyWindow()  # 定义窗口

    w.ui.show()  # 显示窗口

    app.exec()  # 运行主循环
